home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Disc to the Future 2
/
Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin
/
MAC
/
HYPERCAR
/
POPUPMEN
/
POPUP.C
Wrap
C/C++ Source or Header
|
1991-01-18
|
7KB
|
302 lines
/* PopUpMenu 2.0b4
This HyperCard external function presents the user with a pop-up-
menu from which she would then select an item. If no item is
selected NULL is returned to your HyperTalk script. Otherwise,
the ordinal number of the item selected is returned.
PopUpMenu is called with one to four arguments. The first argument
is the menu. This menu is a series of menu items. Each item is
separated by either a comma, semi-colon, carriage-return, line-
feed, or tab. Each item's characters will be added to the menu
with AppendMenu; Thus, any of the AppendMenu meta-characters can
be used (except for the hierarchical menu meta-character).
The second argument is the number of an item to be checked. If
this argument is missing or empty then no item will be checked.
The third and fourth arguments position the pop-up-menu. The
coordinates must be global to the screen. (I have retained
global coordinates to maintain compatibility with PopUpMenu
1.x.) If either of these arguments is missing or empty then
the menu position defaults to the current mouse position.
If all arguments are omitted then version and copyright
information is returned.
Usage example.
on mouseDown
get PopUpMenu( "Color,Mono,Psychedelic", 3 );
if it is empty then
answer "Nothing was selected."
else
answer item it of "Color,Mono,Psychedelic" && "was selected."
end if
end mouseDown
Good luck with your stacks!
Andrew Gilmartin
Computing & Information Services
Box 1885
Brown University
Providence, Rhode Island 02912
andrew@brownvm.brown.edu (internet)
andrew@brownvm (bitnet)
Neither I nor Brown University place any restrictions on the use of
the external HyperTalk function PopUpMenu. I only request that you
credit myself and Brown University; For example,
PopUpMenu by Andrew Gilmartin, Brown University
PopUpMenu has been tested with HyperCard 1.x and HyperCard 2.0. However,
the developers have no desire or ability to support this product, and
therefore PopUpMenu is delivered ╥as is╙ with no expressed or implied
guarantees of operability or support.
*/
#include "MenuMgr.h"
#include "HyperXCmd.h"
#include "utilities.h"
#define NULL 0L
#define FALSE 0
#define TRUE 1
#define loop for(;;)
#define MENU_ID 1024
int gMenuID;
int unusedMenuID( int menuID );
int unusedMenuID( int menuID )
{
while ( GetMHandle( menuID++ ) );
return( menuID - 1 );
} /* unusedMenuID */
MenuHandle popupmenu_create_menu( char * menu_items );
MenuHandle popupmenu_create_menu( menu_items )
char * menu_items;
{
MenuHandle the_menu;
char c;
struct
{
Str255 content;
char * pointer; /* where the next character should be placed in .content */
int length;
} menu_item;
gMenuID = unusedMenuID( MENU_ID );
if ( ( the_menu = NewMenu( gMenuID, "\p" ) ) != NULL )
{
menu_item.pointer = (char *) &menu_item.content;
menu_item.length = 0;
loop
{
switch ( c = *menu_items++ )
{
case ',': /* I figure that these cases should cover most */
case ';': /* uses of PopUpMenu... */
case '\n':
case '\r':
case '\t':
if ( menu_item.length > 0 )
{
*menu_item.pointer = '\0'; /* C strings end in a null! */
CtoPstr( (char *) &menu_item.content );
AppendMenu( the_menu, &menu_item.content );
}
menu_item.pointer = (char *) &menu_item.content;
menu_item.length = 0;
break;
case '\0':
if ( menu_item.length > 0 )
{
*menu_item.pointer = '\0'; /* C strings end in a null! */
CtoPstr( (char *) &menu_item.content );
AppendMenu( the_menu, &menu_item.content );
}
goto outside_loop;
default:
if ( menu_item.length < ( sizeof( menu_item.content ) - 1 ) )
*menu_item.pointer++ = c,
menu_item.length++;
}
}
outside_loop:;
}
return the_menu;
} /* popupmenu_create_menu */
int popupmenu( char * menu_items, int checked_item, Point mouse_location );
int popupmenu( menu_items, checked_item, mouse_location )
char * menu_items;
int checked_item;
Point mouse_location;
{
MenuHandle the_menu;
long the_selected_item = 0;
int the_checked_item;
/* Create Menu */
the_menu = popupmenu_create_menu( menu_items );
if ( the_menu == NULL )
return 0;
/* Check Menu Item */
if ( checked_item > 0 && checked_item <= CountMItems( the_menu ) )
{
CheckItem( the_menu, checked_item, TRUE );
the_checked_item = checked_item;
}
else
{
the_checked_item = 1;
}
/* Add the menu to the system */
InsertMenu( the_menu, -1 );
/* Get Menu Selection */
the_selected_item = PopUpMenuSelect(
the_menu,
mouse_location.v,
mouse_location.h,
the_checked_item );
/* Remove the menu from the system */
DeleteMenu( gMenuID );
DisposeMenu( the_menu );
/* Return user's selection */
return (int) ( the_selected_item & 0x0000FFFF );
} /* popupmenu */
pascal void main( XCmdBlockPtr paramPtr );
pascal void main( paramPtr )
XCmdBlockPtr paramPtr;
{
char * menu_items /* = NULL */;
int checked_item = -1;
int selected_item /* = 0 */;
Point mouse_location;
int _mouse_location;
XCMDSetupA4();
/* Get Mouse Location
We need to get the mouse location early in the external just in case the
user mouses ahead. It would be better if the location of the last mouse
down were available at the toolbox level...
*/
GetMouse( &mouse_location );
LocalToGlobal( &mouse_location );
/* Parse Paramater List */
switch ( paramPtr->paramCount )
{
case 4:
_mouse_location = param_to_integer( paramPtr->params[3] );
if ( _mouse_location > 0 )
mouse_location.v = _mouse_location;
case 3:
_mouse_location = param_to_integer( paramPtr->params[2] );
if ( _mouse_location > 0 )
mouse_location.h = _mouse_location;
case 2:
checked_item = param_to_integer( paramPtr->params[1] );
case 1:
MoveHHi( paramPtr->params[0] );
HLock( paramPtr->params[0] );
menu_items = *(paramPtr->params[0]);
selected_item = popupmenu( menu_items, checked_item, mouse_location );
if ( selected_item != 0 )
paramPtr->returnValue = integer_to_param( selected_item );
HUnlock( paramPtr->params[0] );
break;
case 0:
paramPtr->returnValue = string_to_param(
"PopUpMenu 2.0b4 by Andrew Gilmartin, Brown University" );
break;
default:
break;
}
XCMDRestoreA4();
/* Bye, Bye! */
} /* main */